home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / Late-Breaking Scripting / FWSemInt.cpp < prev    next >
Encoding:
Text File  |  1996-09-19  |  25.6 KB  |  814 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWSemInt.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #ifndef FWSEMINT_H
  11. #include "FWSemInt.h"
  12. #endif
  13.  
  14. // ----- Framework Includes -----
  15.  
  16. #ifndef FWACQSCR_H
  17. #include "FWAcqScr.h"
  18. #endif
  19.  
  20. #ifndef FWEXTMGR_H
  21. #include "FWExtMgr.h"
  22. #endif
  23.  
  24. #ifndef FWPART_H
  25. #include "FWPart.h"
  26. #endif
  27.  
  28. #ifndef PRSIGLUE_H
  29. #include "PRSIGlue.h"
  30. #endif
  31.  
  32. #ifndef FWAPLEVT_H
  33. #include "FWAplEvt.h"
  34. #endif
  35.  
  36. #ifndef FWDSCOPR_H
  37. #include "FWDscOpr.h"
  38. #endif
  39.  
  40. #ifndef FWSCPCAL_H
  41. #include "FWScpCal.h"
  42. #endif
  43.  
  44. #ifndef FWSCPCOL_H
  45. #include "FWScpCol.h"
  46. #endif
  47.  
  48. #ifndef FWSCPTBL_H
  49. #include "FWScptbl.h"
  50. #endif
  51.  
  52. #ifndef FWPRTSCP_H
  53. #include "FWPrtScp.h"
  54. #endif
  55.  
  56. #ifndef FWSCPPRP_H
  57. #include "FWScpPrp.h"
  58. #endif
  59.  
  60. #ifndef FWITERS_H
  61. #include "FWIters.h"
  62. #endif
  63.  
  64. #ifndef FWCONTXT_H
  65. #include "FWContxt.h"
  66. #endif
  67.  
  68. #ifndef FWEVENTU_H
  69. #include "FWEventU.h"
  70. #endif
  71.  
  72. #ifndef FWINK_H
  73. #include "FWInk.h"
  74. #endif
  75.  
  76. #ifndef FWOVLSHP_H
  77. #include "FWOvlShp.h"
  78. #endif
  79.  
  80. #ifndef SOM_FW_OSemanticInterface_xh
  81. #include "SLSemInt.xh"
  82. #endif
  83.  
  84. #ifndef FWSOMENV_H
  85. #include "FWSOMEnv.h"
  86. #endif
  87.  
  88. #ifndef FWSESION_H
  89. #include "FWSesion.h"
  90. #endif
  91.  
  92. // ----- OpenDoc Includes -----
  93.  
  94. #ifndef SOM_Module_OpenDoc_StandardExtensions_defined
  95. #include <StdExts.xh>
  96. #endif
  97.  
  98. #ifndef SOM_Module_OpenDoc_ODRegistry_defined
  99. #include <ODRgstry.xh>
  100. #endif
  101.  
  102. #ifndef SOM_ODNameResolver_xh
  103. #include <NamRslvr.xh>
  104. #endif
  105.  
  106. #ifndef SOM_ODObjectSpec_xh
  107. #include <ODObjSpc.xh>
  108. #endif
  109.  
  110. #ifndef SOM_ODOSLToken_xh
  111. #include <ODOSLTkn.xh>
  112. #endif
  113.  
  114. // ----- Macintosh Includes -----
  115.  
  116. #ifndef __ASREGISTRY__
  117. #include <ASRegistry.h>
  118. #endif
  119.  
  120. //========================================================================================
  121. //    Runtime Information
  122. //========================================================================================
  123.  
  124. #ifdef FW_BUILD_MAC    
  125. #pragma segment fwsemevt
  126. #endif
  127.  
  128. FW_DEFINE_AUTO(FW_CSemanticInterface)
  129.  
  130. //========================================================================================
  131. //    class FW_CSemanticInterface
  132. //========================================================================================
  133.  
  134. //---------------------------------------------------------------------------------------
  135. //    FW_CSemanticInterface::FW_CSemanticInterface
  136. //---------------------------------------------------------------------------------------
  137.  
  138. FW_CSemanticInterface::FW_CSemanticInterface(Environment* ev, FW_CPart* part) :
  139.     fDefaultContainer(FW_DYNAMIC_CAST(FW_MPartScriptable, part)),
  140.     fPart(part),
  141.     fOSLFlags(kAEIDoMinimum),
  142.     fUsingPredispatchProc(FALSE)
  143. {
  144. FW_UNUSED(ev);
  145.  
  146.     FW_END_CONSTRUCTOR
  147.     
  148.     // OpenDoc releases 1.0 - 1.04 (possibly later) have a bug that prevents marking 
  149.     // from working correctly. The bug causes OpenDoc to look at the OSL flags of 
  150.     // the part's containing part when determining whether or not a part marks. This 
  151.     // means that if a part says it does marking, OpenDoc will treat it as if it does 
  152.     // not, but will treat all parts contained by that part as if they do.
  153. }
  154.  
  155. //---------------------------------------------------------------------------------------
  156. //    FW_CSemanticInterface::~FW_CSemanticInterface
  157. //---------------------------------------------------------------------------------------
  158.  
  159. FW_CSemanticInterface::~FW_CSemanticInterface()
  160. {
  161.     FW_START_DESTRUCTOR
  162. }
  163.                                                     
  164. //---------------------------------------------------------------------------------------
  165. //    FW_CSemanticInterface::CreateSOMInterface
  166. //---------------------------------------------------------------------------------------
  167.  
  168. FW_OSemanticInterface* FW_CSemanticInterface::CreateSOMInterface(Environment *ev, 
  169.                                                                 FW_CPart *part, 
  170.                                                                 const char *name,
  171.                                                                 void* refCon)
  172. {    
  173. FW_UNUSED(name);
  174. FW_UNUSED(refCon);
  175.     FW_OSemanticInterface* semInt = new FW_OSemanticInterface;
  176.     semInt->InitODFSemanticInterface(ev, part->GetODPart(ev), FW_CSession::GetODSession(ev), this,  FW_PrivGetSemanticInterfaceGlue());
  177.     
  178.     semInt->SetOSLSupportFlags(ev, fOSLFlags);
  179.     semInt->UsingPredispatchProc(ev, fUsingPredispatchProc);
  180.     
  181.     return semInt;
  182. }
  183.  
  184. //---------------------------------------------------------------------------------------
  185. //    FW_CSemanticInterface::AcquireSOMInterface
  186. //---------------------------------------------------------------------------------------
  187.  
  188. FW_OSemanticInterface* FW_CSemanticInterface::AcquireSOMInterface(Environment* ev)
  189. {
  190.     return (FW_OSemanticInterface*)fPart->GetExtensionManager(ev)->AcquireExtension(ev, kODExtSemanticInterface, FW_kDontCreateExtension);
  191. }
  192.  
  193. //========================================================================================
  194. //  Begin Callbacks
  195. //========================================================================================
  196.  
  197. //---------------------------------------------------------------------------------------
  198. //    FW_CSemanticInterface::CallEventHandler
  199. //---------------------------------------------------------------------------------------
  200.  
  201. void FW_CSemanticInterface::CallEventHandler(Environment* ev, 
  202.                                             FW_CAppleEvent& event, 
  203.                                             FW_CAppleEvent& reply)
  204. {
  205.     // FW_DebugIdentifyPart(ev, fPart->GetLastActiveFrame(ev), FW_kRGBBlack);
  206.  
  207.     FW_CAcquiredScriptable targetObject = AcquireTargetObject(ev, event);
  208.  
  209.     AEKeyword eventClass = event.GetEventClass();
  210.     AEKeyword eventID = event.GetEventID();
  211.     
  212.     // FW_DebugIdentifyPart(ev, fPart->GetLastActiveFrame(ev), FW_kRGBGreen);
  213.  
  214.     targetObject->HandleSemanticEvent(ev, fPart, eventClass, eventID, event, reply);
  215. }
  216.     
  217. //---------------------------------------------------------------------------------------
  218. //    FW_CSemanticInterface::CallCoercionHandler
  219. //---------------------------------------------------------------------------------------
  220.  
  221. void FW_CSemanticInterface::CallCoercionHandler(Environment* ev,
  222.                                                 const FW_CDesc& theDesc,
  223.                                                 ODDescType toType,
  224.                                                 FW_CDesc& theResult)
  225. {
  226. FW_UNUSED(ev);
  227.     FW_Handled handled = FW_CDescCoercionCallbacks::InvokeHandler(theDesc, toType, theResult);
  228.     if (handled == FW_kNotHandled)
  229.         FW_Failure(errAECoercionFail);
  230. }
  231.                                             
  232. //---------------------------------------------------------------------------------------
  233. //    FW_CSemanticInterface::CallPredispatchProc
  234. //---------------------------------------------------------------------------------------
  235.  
  236. void FW_CSemanticInterface::CallPredispatchProc(Environment* ev, 
  237.                                                 FW_CAppleEvent& event,
  238.                                                 FW_CAppleEvent& reply)
  239. {
  240. FW_UNUSED(ev);
  241. FW_UNUSED(event);
  242. FW_UNUSED(reply);
  243.     FW_Failure(errAEEventNotHandled);
  244. }
  245.  
  246. //---------------------------------------------------------------------------------------
  247. //    FW_CSemanticInterface::CallObjectAccessor
  248. //---------------------------------------------------------------------------------------
  249.  
  250. void FW_CSemanticInterface::CallObjectAccessor(Environment* ev,
  251.                                                 ODDescType desiredClass,
  252.                                                 ODOSLToken* container,
  253.                                                 ODDescType containerClass,
  254.                                                 ODDescType form,
  255.                                                 FW_CDesc& selectionData,
  256.                                                 ODOSLToken* value)
  257. {
  258.     // FW_DebugIdentifyPart(ev, fPart->GetLastActiveFrame(ev), FW_kRGBBlue);
  259.     
  260.     FW_CDesc containedObjectToken(GetDescFromToken(ev, value));
  261.     FW_CDesc containerToken(GetDescFromToken(ev, container));
  262.     FW_CAcquiredScriptable acquiredObject;
  263.     
  264.             // OpenDoc 1.0 doesn't handle OSLSupportFlags correctly.
  265.             // Instead of respecting our request for object marking,
  266.             // we get a container token here that is a list built
  267.             // by the OD OSL. For now, we'll simulate marking by
  268.             // building generating a collection of marked objects ourselves.
  269.             
  270.     if (containerToken.IsList() && desiredClass == cProperty)
  271.     {
  272.         ODDescType whichProperty;
  273.         
  274.         selectionData >> whichProperty;
  275.         acquiredObject = CreateCollectionFromList(ev, fPart, containerToken, whichProperty);
  276.     }
  277.     else
  278.     {
  279.         if (containerClass == cPart)
  280.         {
  281.             FW_MPartScriptable* part = GetDefaultContainer();
  282.             acquiredObject = part->AcquireObjectContainedInPart(ev, desiredClass, form, selectionData);
  283.         }
  284.         else
  285.         {
  286.             FW_MScriptable* containerObject;
  287.             
  288.             if (containerToken.IsNullDescriptor())
  289.                 containerObject = GetDefaultContainer();
  290.             else
  291.                 containerObject = ::FW_ExtractScriptableFromDesc(containerToken);
  292.         
  293.             acquiredObject = containerObject->AcquireContainedObject(ev, fPart, desiredClass, form, selectionData);
  294.         }
  295.         
  296.     }
  297.     
  298.     if (acquiredObject != NULL)
  299.         ::FW_InsertScriptableIntoDesc(acquiredObject, containedObjectToken);
  300.     else
  301.         FW_Failure(errAEEventNotHandled);
  302. }
  303.                                                     
  304. //---------------------------------------------------------------------------------------
  305. //    FW_CSemanticInterface::CallCompareProc
  306. //---------------------------------------------------------------------------------------
  307.  
  308. void FW_CSemanticInterface::CallCompareProc(Environment* ev,
  309.                                             ODDescType oper,
  310.                                             ODOSLToken* obj1,
  311.                                             ODOSLToken* obj2,
  312.                                             ODBoolean* result)
  313. {
  314.     FW_CDesc desc1(GetDescFromToken(ev, obj1));
  315.     FW_CDesc desc2(GetDescFromToken(ev, obj2));
  316.         
  317.     if (desc1.DescriptorType() == FW_kSemanticObjectTokenType)
  318.     {
  319.         FW_MScriptable* semanticObject = ::FW_ExtractScriptableFromDesc(desc1);
  320.         *result = semanticObject->CompareScriptableObjects(ev, fPart, oper, desc2);
  321.     }
  322.     else
  323.         FW_Failure(errAEEventNotHandled);
  324. }
  325.                                                     
  326. //---------------------------------------------------------------------------------------
  327. //    FW_CSemanticInterface::CallCountProc
  328. //---------------------------------------------------------------------------------------
  329. void FW_CSemanticInterface::CallCountProc(Environment* ev,
  330.                                         ODDescType desiredClass,
  331.                                         ODDescType containerClass,
  332.                                         ODOSLToken* container,
  333.                                         ODSLong* result)
  334. {
  335.     FW_CDesc containerToken(GetDescFromToken(ev, container));
  336.     
  337.     long                elementCount = 0;
  338.  
  339.     if (containerClass == cPart)
  340.     {
  341.         elementCount = GetDefaultContainer()->CountElementsInPart(ev, desiredClass);
  342.     }
  343.     else
  344.     {
  345.         FW_MScriptable*    containerObject = NULL;
  346.  
  347.         if (containerToken.IsNullDescriptor())
  348.             containerObject = GetDefaultContainer();
  349.         else
  350.             containerObject = ::FW_ExtractScriptableFromDesc(containerToken);
  351.         
  352.         elementCount = containerObject->CountElements(ev, fPart, desiredClass);
  353.     }
  354.     
  355.     *result = elementCount;
  356. }
  357.  
  358. //---------------------------------------------------------------------------------------
  359. //    FW_CSemanticInterface::CallDisposeTokenProc
  360. //---------------------------------------------------------------------------------------
  361. void FW_CSemanticInterface::CallDisposeTokenProc(Environment* ev, ODOSLToken* unneededToken)
  362. {
  363.     FW_CDesc token(GetDescFromToken(ev, unneededToken));
  364.     
  365.     if (token.DescriptorType() == FW_kSemanticObjectTokenType)
  366.     {
  367.         FW_MScriptable* scriptableObject = ::FW_ExtractScriptableFromDesc(token);
  368.         scriptableObject->ReleaseScriptable();
  369.         token.Clear();
  370.     }
  371.     else
  372.         FW_Failure(errAEEventNotHandled);
  373. }
  374.                                                         
  375. //---------------------------------------------------------------------------------------
  376. //    FW_CSemanticInterface::CallGetErrDescProc
  377. //---------------------------------------------------------------------------------------
  378. void FW_CSemanticInterface::CallGetErrDescProc(Environment* ev, ODDesc** errDesc)
  379. {
  380. FW_UNUSED(ev);
  381. FW_UNUSED(errDesc);
  382.     FW_Failure(errAEEventNotHandled);
  383. }
  384.                                                     
  385. //---------------------------------------------------------------------------------------
  386. //    FW_CSemanticInterface::CallGetMarkTokenProc
  387. //---------------------------------------------------------------------------------------
  388. void FW_CSemanticInterface::CallGetMarkTokenProc(Environment* ev,
  389.                                                 ODOSLToken* dContainerToken,
  390.                                                 ODDescType    containerClass,
  391.                                                 ODOSLToken* result)
  392. {
  393. FW_UNUSED(dContainerToken);
  394. FW_UNUSED(containerClass);
  395.     
  396.     // FW_DebugIdentifyPart(ev, fPart->GetLastActiveFrame(ev), FW_kRGBBlue);
  397.     
  398.     FW_CDesc collectionToken(GetDescFromToken(ev, result));
  399.  
  400.     FW_CAcquiredScriptable collection = FW_NEW(FW_CScriptableCollection, ());
  401.     ::FW_InsertScriptableIntoDesc(collection, collectionToken);
  402. }
  403.                                                         
  404. //---------------------------------------------------------------------------------------
  405. //    FW_CSemanticInterface::CallMarkProc
  406. //---------------------------------------------------------------------------------------
  407. void FW_CSemanticInterface::CallMarkProc(Environment* ev,
  408.                                         ODOSLToken* objectToMarkToken,
  409.                                         ODOSLToken* markingListToken,
  410.                                         ODSLong index)
  411. {
  412. FW_UNUSED(index);
  413.  
  414.     // FW_DebugIdentifyPart(ev, fPart->GetLastActiveFrame(ev), FW_kRGBRed);
  415.     
  416.     FW_CDesc objectToMarkDesc(GetDescFromToken(ev, objectToMarkToken));
  417.     FW_CDesc markingListDesc(GetDescFromToken(ev, markingListToken));
  418.     
  419.     FW_MScriptable* objectToMark = ::FW_ExtractScriptableFromDesc(objectToMarkDesc);
  420.     FW_CScriptableCollection* collection = 
  421.         FW_DYNAMIC_CAST(FW_CScriptableCollection, ::FW_ExtractScriptableFromDesc(markingListDesc));
  422.     
  423.     collection->Add(objectToMark);
  424. }
  425.     
  426. //---------------------------------------------------------------------------------------
  427. //    FW_CSemanticInterface::CallAdjustMarksProc
  428. //---------------------------------------------------------------------------------------
  429. void FW_CSemanticInterface::CallAdjustMarksProc(Environment* ev,
  430.                                                 ODSLong newStart,
  431.                                                 ODSLong newStop,
  432.                                                 ODOSLToken* markToken)
  433. {
  434.     // FW_DebugIdentifyPart(ev, fPart->GetLastActiveFrame(ev), FW_kRGBGreen);
  435.     
  436.     FW_CDesc markingListDesc(GetDescFromToken(ev, markToken));
  437.     FW_CScriptableCollection* collection = 
  438.         FW_DYNAMIC_CAST(FW_CScriptableCollection, ::FW_ExtractScriptableFromDesc(markingListDesc));
  439.     
  440.     collection->AdjustMarks(ev, newStart, newStop);
  441. }
  442.     
  443. //---------------------------------------------------------------------------------------
  444. //    FW_CSemanticInterface::GetOSLSupportFlags
  445. //---------------------------------------------------------------------------------------
  446.  
  447. ODSShort FW_CSemanticInterface::GetOSLSupportFlags(Environment* ev)
  448. {
  449. FW_UNUSED(ev);
  450.     return fOSLFlags;
  451.  
  452. //---------------------------------------------------------------------------------------
  453. //    FW_CSemanticInterface::SetOSLSupportFlags
  454. //---------------------------------------------------------------------------------------
  455.  
  456. void FW_CSemanticInterface::SetOSLSupportFlags(Environment* ev, ODSShort flags)
  457. {
  458.     fOSLFlags = flags;
  459.     
  460.     FW_OSemanticInterface* semInt = AcquireSOMInterface(ev);
  461.     if (semInt)
  462.     {
  463.         semInt->SetOSLSupportFlags(ev, flags);
  464.         semInt->Release(ev);
  465.     }
  466. }
  467.                                                     
  468. //---------------------------------------------------------------------------------------
  469. //    FW_CSemanticInterface::UsingPredispatchProc
  470. //---------------------------------------------------------------------------------------
  471.  
  472. void FW_CSemanticInterface::UsingPredispatchProc(Environment* ev, ODBoolean usingNotUsing)
  473. {
  474.     fUsingPredispatchProc = usingNotUsing;
  475.     
  476.     ODSemanticInterface* semInt = AcquireSOMInterface(ev);
  477.     if (semInt)
  478.     {
  479.         semInt->UsingPredispatchProc(ev, usingNotUsing);
  480.         semInt->Release(ev);
  481.     }
  482. }
  483.  
  484. //---------------------------------------------------------------------------------------
  485. //    FW_CSemanticInterface::CreateCollectionFromList
  486. //---------------------------------------------------------------------------------------
  487.  
  488. FW_MScriptable* FW_CSemanticInterface::CreateCollectionFromList(Environment* ev,
  489.                                                                     FW_CPart* part,
  490.                                                                     const FW_CDesc& objectList,
  491.                                                                     ODDescType whichProperty) const
  492. {
  493.     FW_ASSERT(objectList.IsList());
  494.     
  495.     // FW_DebugIdentifyPart(ev, fPart->GetLastActiveFrame(ev), FW_kRGBPurple);
  496.     
  497.     FW_CScriptableCollection* collection = FW_NEW(FW_CScriptableCollection, ());
  498.     
  499.     FW_CDesc     currentODToken;
  500.     FW_CDesc    currentToken;
  501.     long         itemsInList = objectList.GetItemCount();
  502.     
  503.     for (long index = 1; index <= itemsInList; index++)
  504.     {
  505.         currentODToken.Clear();
  506.         currentToken.Clear();
  507.         
  508.         objectList.GetDescFromList(index, currentODToken);
  509.         currentToken = GetDescFromToken(ev, currentODToken);
  510.         
  511.         FW_MScriptable* semObj = ::FW_ExtractScriptableFromDesc(currentToken);
  512.         
  513.         if (whichProperty != keyNoKey)
  514.         {
  515.             FW_CPropertyDesignator* propDesignator;
  516.  
  517.             propDesignator = FW_NEW(FW_CPropertyDesignator, (part, semObj, whichProperty));
  518.             collection->Add(propDesignator);
  519.         }
  520.         else
  521.             collection->Add(semObj);
  522.     }
  523.     return collection;
  524. }
  525.  
  526. //---------------------------------------------------------------------------------------
  527. //    FW_CSemanticInterface::GetDescFromToken
  528. //---------------------------------------------------------------------------------------
  529.  
  530. ODDesc* FW_CSemanticInterface::GetDescFromToken(Environment* ev, 
  531.                                                 ODOSLToken* token) const
  532. {
  533.     ODNameResolver* nameResolver = FW_CSession::GetNameResolver(ev);
  534.     return (nameResolver->IsODToken(ev, token) ? nameResolver->GetUserToken(ev, token) : token);
  535. }
  536.  
  537. //---------------------------------------------------------------------------------------
  538. //    FW_CSemanticInterface::ParseStandardPartToken
  539. //---------------------------------------------------------------------------------------
  540.  
  541. void FW_CSemanticInterface::ParseStandardPartToken(Environment* ev,
  542.                                                 const FW_CDesc& token, 
  543.                                                 ODPart** odPart, 
  544.                                                 ODFrame** odFrame) const
  545. {
  546. FW_UNUSED(ev);    
  547.     struct FW_SPrivStandardPartToken
  548.     {
  549.         ODFrame* fFrame;
  550.         ODPart* fPart;
  551.     };
  552.  
  553.     const FW_CDesc* partToken = &token;
  554.     FW_CDesc coercedToken;
  555.     
  556.     if (token.DescriptorType() != kODStandardPartTokenType)
  557.     {
  558.         token.Coerce(kODStandardPartTokenType, coercedToken);
  559.         partToken = &coercedToken;
  560.     }
  561.     
  562.     FW_ASSERT(token.DescriptorType() == kODStandardPartTokenType);
  563.     FW_ASSERT(token.PlatformDataHandle() != NULL);
  564.     
  565.     FW_SPrivStandardPartToken standardToken;
  566.     
  567.     partToken->GetDataByPtr(typeWildCard, &standardToken, NULL, sizeof(FW_SPrivStandardPartToken));
  568.     
  569.     if (odPart)
  570.         *odPart = standardToken.fPart;
  571.     
  572.     if (odFrame)
  573.         *odFrame = standardToken.fFrame;
  574. }
  575.  
  576. //---------------------------------------------------------------------------------------
  577. //    FW_CSemanticInterface::IsStandardPartToken
  578. //---------------------------------------------------------------------------------------
  579.  
  580. FW_Boolean FW_CSemanticInterface::IsStandardPartToken(const FW_CDesc& token) const
  581. {
  582.     FW_Boolean result = (token.DescriptorType() == kODStandardPartTokenType);
  583.     
  584.     if (!result)
  585.     {    
  586.         FW_CDesc coercedDesc;
  587.         
  588.         FW_TRY
  589.         {
  590.             token.Coerce(kODStandardPartTokenType, coercedDesc);
  591.             if (coercedDesc.DescriptorType() == kODStandardPartTokenType)
  592.                 result = true;
  593.         }
  594.         FW_CATCH_BEGIN
  595.         FW_CATCH_EVERYTHING()
  596.         {
  597.             // don't propogate exceptions
  598.         }
  599.         FW_CATCH_END
  600.     }
  601.     
  602.     return result;
  603. }
  604.  
  605. //---------------------------------------------------------------------------------------
  606. //    FW_CSemanticInterface::AcquireTargetObject
  607. //---------------------------------------------------------------------------------------
  608.  
  609. FW_MScriptable* FW_CSemanticInterface::AcquireTargetObject(Environment* ev,
  610.                                                     FW_CAppleEvent& event)
  611. {
  612.     ODNameResolver* nameResolver = FW_CSession::GetNameResolver(ev);
  613.     FW_MScriptable* result = NULL;
  614.     
  615.     if (event.HasDataKey(keyDirectObject))
  616.     {
  617.         FW_CDesc directObjectToken;
  618.         
  619.         event.GetDataByDesc(directObjectToken, keyDirectObject);
  620.         
  621.         // the direct object is not always an object specifier (e.g "beep 1")
  622.         if (nameResolver->IsODToken(ev, directObjectToken))
  623.             result = AcquireScriptableFromToken(ev, directObjectToken);
  624.     }
  625.     
  626.     if (result == NULL && event.HasAttribute(keySubjectAttr))
  627.     {
  628.         FW_CDesc subjectDesc;
  629.         FW_CDesc resolvedSubjectAttribute;
  630.  
  631.         event.GetSubject(subjectDesc);
  632.         
  633.         // With OpenDoc 1.1 and earlier, the subject attribute is an unresolved
  634.         // object specifier. With OpenDoc 1.2 and later, the subject attribute
  635.         // should be a user token representing a resolved object specifier. This
  636.         // code handles either case.
  637.         if (subjectDesc.DescriptorType() == typeObjectSpecifier)
  638.         {
  639.             Resolve(ev, subjectDesc, resolvedSubjectAttribute);
  640.             subjectDesc = resolvedSubjectAttribute;
  641.         }
  642.         
  643.         FW_TRY
  644.         {
  645.             result = AcquireScriptableFromToken(ev, subjectDesc);
  646.         }
  647.         FW_CATCH_BEGIN
  648.         FW_CATCH_EVERYTHING()
  649.         {
  650.             nameResolver->DisposeToken(ev, resolvedSubjectAttribute);
  651.             FW_THROW_SAME();
  652.         }
  653.         FW_CATCH_END
  654.         
  655.         nameResolver->DisposeToken(ev, resolvedSubjectAttribute);
  656.     }
  657.     
  658.     if (result == NULL)
  659.         FW_Failure(errAEEventNotHandled);
  660.     
  661.     return result;
  662. }
  663.  
  664. //---------------------------------------------------------------------------------------
  665. //    FW_CSemanticInterface::Resolve
  666. //---------------------------------------------------------------------------------------
  667.  
  668. void FW_CSemanticInterface::Resolve(Environment* ev,
  669.                                     const FW_CDesc& objectSpec,
  670.                                     FW_CDesc& odfToken,
  671.                                     ODPart* contextPart) const
  672. {
  673.     if (objectSpec.IsNullDescriptor())
  674.     {
  675.         odfToken.Clear();
  676.     }
  677.     else
  678.     {    
  679.         ODNameResolver* nameResolver = FW_CSession::GetNameResolver(ev);
  680.         
  681.         nameResolver->Resolve(ev, objectSpec, odfToken, contextPart);
  682.         odfToken.SetOwnsODData(FALSE);
  683.     }
  684. }
  685.  
  686. //---------------------------------------------------------------------------------------
  687. //    FW_CSemanticInterface::AcquireScriptableFromToken
  688. //---------------------------------------------------------------------------------------
  689.  
  690. FW_MScriptable* FW_CSemanticInterface::AcquireScriptableFromToken(Environment* ev,
  691.                                                                 const FW_CDesc& odToken) const
  692. {    
  693.     FW_MScriptable* scriptable = NULL;
  694.     FW_CDesc        ourToken = GetDescFromToken(ev, odToken);
  695.     ODDescType        ourTokenType = ourToken.DescriptorType();
  696.     FW_Boolean        ourTokenIsStandardPartToken = IsStandardPartToken(ourToken);
  697.     ODFrame*        tokenFrame;
  698.     ODPart*            tokenPartWrapper = NULL;
  699.     ODPart*         realTokenPart = NULL;
  700.     ODPart*            myPartWrapper = NULL;
  701.     ODPart*            myRealPart = NULL;
  702.     
  703.     // An event that has no direct object, or whose direct object is not an object specifier,
  704.     // has a standard part token inside of the odToken that describes the part at which the
  705.     // event is targeted. Bugs in OpenDoc cause the event to sometimes get dispatched to the
  706.     // wrong part first. We attempt to identify this case here, and throw an exception when
  707.     // we receive an event not targeted at us. This causes OpenDoc to ultimately dispatch the
  708.     // event to the correct target.
  709.     
  710.     // If the token contains standard part token, we parse it ourselves to extract the target
  711.     // part. The OpenDoc team has agreed that the structure of standard part tokens must
  712.     // be exposed to correctly implement this recipe. The structure of standard part
  713.     // tokens will not change in future versions of OpenDoc.
  714.     // If the token does not contain a standard part token, we ask the name resolver for
  715.     // the context of the token.
  716.     
  717.     // if the odToken is the null descriptor, there was no direct object and no subject
  718.     // attribute. If this is the case, the event _must_ be targeted at the root part,
  719.     // and we _must_ be the root part, since events are never mistakenly dispatched to
  720.     // parts embedded in the real target.
  721.     if (!odToken.IsNullDescriptor())
  722.     {
  723.         if (ourTokenIsStandardPartToken)
  724.             ParseStandardPartToken(ev, ourToken, &tokenPartWrapper, NULL);
  725.         else
  726.             FW_CSession::GetNameResolver(ev)->GetContextFromToken(ev, odToken, &tokenPartWrapper, &tokenFrame);
  727.         
  728.         if (tokenPartWrapper != NULL)
  729.         {
  730.             realTokenPart = tokenPartWrapper->GetRealPart(ev);
  731.             if (realTokenPart)    // don't release it if we didn't acquire it
  732.                 tokenPartWrapper->ReleaseRealPart(ev);
  733.         }
  734.         else
  735.             realTokenPart = NULL;
  736.         
  737.         FW_ASSERT(realTokenPart != NULL);
  738.         
  739.         myPartWrapper = GetPart()->GetODPart(ev);
  740.         myRealPart = myPartWrapper->GetRealPart(ev);
  741.         if (myRealPart)    // don't release it if we didn't acquire it
  742.             myPartWrapper->ReleaseRealPart(ev);
  743.         
  744.         FW_ASSERT(myRealPart != NULL);
  745.             
  746.         // If the part we got from parsing the token or calling GetContextFromToken is not
  747.         // our part, then the event was mistakenly dispatched to us.
  748.         
  749.         if (realTokenPart == NULL || myRealPart == NULL || realTokenPart != myRealPart)
  750.             FW_Failure(errAEEventNotHandled);
  751.     }
  752.     
  753.     if (ourToken.IsNullDescriptor() || ourTokenIsStandardPartToken)
  754.     {
  755.         scriptable = GetDefaultContainer();
  756.         scriptable->AcquireScriptable();
  757.     }
  758.     else if (ourTokenType == FW_kSemanticObjectTokenType)
  759.     {
  760.         scriptable = ::FW_ExtractScriptableFromDesc(ourToken);
  761.         scriptable->AcquireScriptable();
  762.     }
  763.     else if (ourToken.IsList())
  764.     {
  765.         scriptable = CreateCollectionFromList(ev, fPart, ourToken);
  766.     }
  767.     else
  768.         FW_Failure(errAEEventNotHandled);
  769.         
  770.     return scriptable;
  771. }
  772.  
  773. //---------------------------------------------------------------------------------------
  774. //    FW_DebugIdentifyPart:
  775. //    This utility method is for debugging semantic event handling in nested parts.
  776. //    A circle of the specified color will be briefly displayed in the top left
  777. //    corner of the first facet of the specified frame. This method does not attempt 
  778. //  to redraw or invalidate the content area obscured by the circle.
  779. //
  780. //    Note: This method may not be a permanent part of the ODF API.
  781. //---------------------------------------------------------------------------------------
  782.  
  783. void FW_DebugIdentifyPart(Environment* ev, FW_CFrame* frame, const FW_CColor& color)
  784. {
  785.     if (frame)
  786.     {
  787.         FW_CFrameFacetIterator iter(ev, frame);
  788.         FW_CViewContext vc(ev, frame, iter.First(ev), NULL);
  789.         FW_CRect rect(FW_kFixed0, FW_kFixed0, FW_IntToFixed(10), FW_IntToFixed(10));
  790.         
  791.         FW_CInk ink;
  792.         ink.SetForeColor(color);
  793.         ink.SetTransferMode(FW_kCopy);
  794.         FW_COvalShape::RenderOval(vc, rect, FW_kFill, ink);
  795.         FW_WaitFor(20);
  796.         ink.SetTransferMode(FW_kErase);
  797.         FW_COvalShape::RenderOval(vc, rect, FW_kFill, ink);
  798.     }
  799. }
  800.                                                     
  801. //========================================================================================
  802. //  End Callbacks
  803. //========================================================================================
  804.  
  805. //---------------------------------------------------------------------------------------
  806. //    FW_CSemanticInterface::PrivCreate
  807. //---------------------------------------------------------------------------------------
  808.  
  809. ODExtension* FW_CSemanticInterface::PrivCreate(Environment* ev, FW_CPart* part, const char* name, void* refCon)
  810. {
  811.     return (part->GetSemanticInterface(ev)->CreateSOMInterface(ev, part, name, refCon));        
  812. }
  813.